<?php

//防止恶意调用
if (!defined('IN_MOD'))
{
    die('Hacking attempt');
}

define('GPC',get_magic_quotes_gpc());
global $configinfo;
$configinfo['config']=1;// 模块程序配置
/* MYSQL命令集 ********************* 
** mysql 【连接Mysql数据库】
** mysqladmin 【修改用户密码】
** grant on 【增加新用户并控制其权限】
** create 【创建数据库】
** show databases 【显示所有数据库】
** drop 【删除数据库】
** use 【使用数据库】
** select 【当前选择（连接）的数据库】
** create table 【创建数据表】
** desc 【获取数据表结构】
** drop table 【删除数据表】
** insert into 【向表中插入数据】
** select from 【查询表中的数据】
** delete from 【删除记录】
** update set 【修改表中的数据】
** alter add 【增加表的字段】
** rename 【修改表名】
** mysqldump 【备份数据库】
***********************************/

// 这里采用递归形式
// 转换实体-无限层次数组
// 将接收数据进行转义
function modulesqlstring(&$_string="",$type="default")
{
	global $configinfo;
	
	if(is_array($_string) || is_object($_string))
	{
		foreach ($_string as $_key => $_value)
		{
			if(is_array($_value))
			{
				$_string[$_key] = modulesqlstring($_value,$type);
			
			// 新增接收对象参数过滤转义
			}elseif(is_object($_string))
			{
				$_string->$_key = modulesqlstring($_value,$type);
				
			}else{
				if($type == 'join' || $type == 'default')
				{
					if(!GPC)$_string[$_key] = moduledatajoin($_value);
				}
				if($type == 'html' || $type == 'default')
				{
					$_string[$_key] = htmlspecialchars($_value);	
				}
			}
		}
		
	}else{
		if($type == 'join' || $type == 'default')
		{
			if(!GPC)$_string = moduledatajoin($_string);
		}
		if($type == 'html' || $type == 'default')
		{
			$_string = htmlspecialchars($_string);
		}
	}

	return $_string;
}

// 数据入库 转义 特殊字符 传入值可为字符串 或 一维数组 
function moduledatajoin($data="")
{
   if(get_magic_quotes_gpc() == false)
   {
	if (is_array($data))
	{
	 foreach ($data as $k => $v)
	 {
	 $data[$k] = addslashes($v);
	 }
	}
	else
	{
	$data = addslashes($data);
	}
   }
   return $data;
}
 
// 数据出库 还原 特殊字符 传入值可为字符串 或 一/二维数组
function moduledatarevert($data="")
{
   if (is_array($data))
   {
	foreach ($data as $k1 => $v1)
	{
	 if (is_array($v1))
	 {
	  foreach ($v1 as $k2 => $v2)
	  {
	  $data[$k1][$k2] = stripslashes($v2);
	  }
	 }
	 else
	 {
	 $data[$k1] = stripslashes($v1);
	 }
	}
   }
   else
   {
   $data = stripslashes($data);
   }
   return $data;
}
 
// 数据显示 还原 数据格式 主要用于内容输出 传入值可为字符串 或 一/二维数组
// 执行此方法前应先data_revert()，表单内容无须此还原
function moduledatashow($data="")
{
   if (is_array($data))
   {
	foreach ($data as $k1 => $v1)
	{
	 if (is_array($v1))
	 {
	  foreach ($v1 as $k2 => $v2)
	  {
	  $data[$k1][$k2]=nl2br(htmlspecialchars($data[$k1][$k2]));
	  $data[$k1][$k2]=str_replace(" "," ",$data[$k1][$k2]);
	  $data[$k1][$k2]=str_replace("\n","<br>\n",$data[$k1][$k2]);
	  }
	 }
	 else
	 {
	 $data[$k1]=nl2br(htmlspecialchars($data[$k1]));
	 $data[$k1]=str_replace(" "," ",$data[$k1]);
	 $data[$k1]=str_replace("\n","<br>\n",$data[$k1]);
	 }
	}
   }
   else
   {
   $data=nl2br(htmlspecialchars($data));
   $data=str_replace(" "," ",$data);
   $data=str_replace("\n","<br>\n",$data);
   }
   return $data;
}

// GPC安全过滤将接收数据进行转义
global $_MGPC_POST,$_MGPC_GET,$_MGPC_REQ,$_MGPC_COOKIE,$_MGPC_SESSION;
if(!isset($_MGPC_POST))$_MGPC_POST = array();
if(!isset($_MGPC_GET))$_MGPC_GET = array();
if(!isset($_MGPC_REQ))$_MGPC_REQ = array();
if(!isset($_MGPC_COOKIE))$_MGPC_COOKIE = array();
if(!isset($_MGPC_SESSION))$_MGPC_SESSION = array();
if(isset($_POST))
{
	$postdata = $_POST;
	$mgpc_post_data = modulesqlstring($postdata,$configinfo['aqtype']);
	$_MGPC_POST = array_merge($_MGPC_POST,$mgpc_post_data);
}
if(isset($_GET))
{
	$getdata = $_GET;
	$mgpc_get_data = modulesqlstring($getdata,$configinfo['aqtype']);
	$_MGPC_GET = array_merge($_MGPC_GET,$mgpc_get_data);
}
if(isset($_REQUEST))
{
	$requestdata = $_REQUEST;
	$mgpc_req_data = modulesqlstring($requestdata,$configinfo['aqtype']);
	$_MGPC_REQ = array_merge($_MGPC_REQ,$mgpc_req_data);
}
if(isset($_COOKIE))
{
	$cookiedata = $_COOKIE;
	$mgpc_cookie_data = modulesqlstring($cookiedata,$configinfo['aqtype']);
	$_MGPC_COOKIE = array_merge($_MGPC_COOKIE,$mgpc_cookie_data);
}
if(isset($_SESSION))
{
	$sessiondata = $_SESSION;
	$mgpc_session_data = modulesqlstring($sessiondata,$configinfo['aqtype']);
	$_MGPC_SESSION = array_merge($_MGPC_SESSION,$mgpc_session_data);
}

// 数据过滤为整数
function moduleintval($varinfo="")
{
	$res = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;	
	
	return $res;
}

// 数据过滤为字符串
function modulestring($varinfo="")
{
	$res = isset($varinfo) ? trim($varinfo) : '';
	
	return $res;
}

//防止SQL语句注入
function modulesqlcheck($sql_str="")
{
	$check = preg_match('/select|insert|update|delete|`|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile/i', $sql_str);// 新增（`）接收的字段操作数据库时SQL注入安全处理
	if($check)
	{
		echo "非法操作！输入非法注入内容！";
		exit;
	}else{
		return $sql_str;
	}
}

// 防数字SQL注入，接收数字安全过滤
function moduleaqvar($varnamearr=array(),$type='intval')
{
	global $_MGPC_REQ;
	
	$moduleaqvar = array();
	
	// 整数
	if($type == 'intval' && is_array($varnamearr))
	{
		foreach($varnamearr as $key=>$val)
		{
			if(is_array($val))
			{
				if($val[0] && !$val[1] && !$val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$var[0]]);
					$moduleaqvar[$val[0]] = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;
				}
				if($val[0] && $val[1] && !$val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$val[0]][$val[1]]);
					$moduleaqvar[$val[0]][$val[1]] = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;
				}
				if($val[0] && $val[1] && $val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$val[0]][$val[1]][$val[2]]);
					$moduleaqvar[$val[0]][$val[1]][$val[2]] = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;
				}
			}else{
				$varinfo = modulesqlcheck($_MGPC_REQ[$val]);
				$moduleaqvar[$val] = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;
			}
		}
	}
	
	// 字符串
	if($type == 'string' && is_array($varnamearr))
	{
		foreach($varnamearr as $key=>$val)
		{
			if(is_array($val))
			{
				if($val[0] && !$val[1] && !$val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$var[0]]);
					$moduleaqvar[$val[0]] = isset($varinfo) ? trim($varinfo) : '';
				}
				if($val[0] && $val[1] && !$val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$val[0]][$val[1]]);
					$moduleaqvar[$val[0]][$val[1]] = isset($varinfo) ? trim($varinfo) : '';
				}
				if($val[0] && $val[1] && $val[2])
				{
					$varinfo = modulesqlcheck($_MGPC_REQ[$val[0]][$val[1]][$val[2]]);
					$moduleaqvar[$val[0]][$val[1]][$val[2]] = isset($varinfo) ? trim($varinfo) : '';
				}
			}else{
				$varinfo = modulesqlcheck($_MGPC_REQ[$val]);
				$moduleaqvar[$val] = isset($varinfo) ? trim($varinfo) : '';
			}
		}
	}
	
	return $moduleaqvar;
}
// 直接获取过滤后的接收值
function moduleaqvarval($var="",$type='intval',$datatype='request',$datamysql="")
{
	global $_MGPC_REQ,$_MGPC_GET,$_MGPC_POST,$_MGPC_COOKIE,$_MGPC_SESSION;
	
	// 获取接收数据
	if($datatype == 'cookie')
	{
		$getdata = $_MGPC_COOKIE;
		
	}else if($datatype == 'session')
	{
		$getdata = $_MGPC_SESSION;
		
	}else if($datatype == 'get')
	{
		$getdata = $_MGPC_GET;
		
	}else if($datatype == 'post')
	{
		$getdata = $_MGPC_POST;
		
	}else{
		$getdata = $_MGPC_REQ;
	}
	
	// 已接收过的数据（如已接收数组，再重新对应过滤输出的值）
	if($datatype == 'data')
	{
		$varinfo = $var;
	
	// 非接收的外部数据
	}else if($datatype == 'outdata')
	{
		$varinfo = modulesqlstring($var,$datamysql);
	
	// 通过http接收的数据
	}else{
		// 接收数据数组
		if(is_array($var))
		{
			if($var[0] && !$var[1] && !$var[2])$varinfo = $getdata[$var[0]];
			if($var[0] && $var[1] && !$var[2])$varinfo = $getdata[$var[0]][$var[1]];
			if($var[0] && $var[1] && $var[2])$varinfo = $getdata[$var[0]][$var[1]][$var[2]];
		}else{
			$varinfo = $getdata[$var];
		}
	}
	
	// 整数
	if($type == 'intval')
	{
		$varinfo = modulesqlcheck($varinfo);
		$res = isset($varinfo) && intval($varinfo) > 0 ? intval($varinfo) : 0;
	}
	
	// 浮点小数
	if($type == 'floatval')
	{
		$varinfo = modulesqlcheck($varinfo);
		$res = isset($varinfo) && floatval($varinfo) > 0 ? floatval($varinfo) : 0;
	}
	
	// 字符串
	if($type == 'string')
	{
		$varinfo = modulesqlcheck($varinfo);
		$res = isset($varinfo) ? trim($varinfo) : '';
	}
	
	// 数组
	if($type == 'array')
	{
		$res = $varinfo;
	}
	
	return $res;
}
// 将数据存入REQ的接收数据中
function moduleaqvardata($varnamearr=array(),$content="")
{
	global $_MGPC_REQ;
	
	if(is_array($varnamearr))
	{
		foreach($varnamearr as $key=>$val)
		{
			$val = explode("-", $val);
			if(is_array($val))
			{
				if($val[0] && !$val[1] && !$val[2])$_MGPC_REQ[$val[0]] = modulesqlcheck($content[$key]);
				if($val[0] && $val[1] && !$val[2])$_MGPC_REQ[$val[0]][$val[1]] = modulesqlcheck($content[$key]);
				if($val[0] && $val[1] && $val[2])$_MGPC_REQ[$val[0]][$val[1]][$val[2]] = modulesqlcheck($content[$key]);
			}
		}
	}
}

// 使用开始标记和结束标记解析字符串中的变量
function modulestr($str="",$phpvarok=0)
{
	$data = <<<MODULESTR
		$str
MODULESTR;
	
	return $data;
}

// 新增模板解析函数与变量
// 仅限模块程序配置
if($configinfo['config']==1)
{
	function moduleeval($funhtml="",$datahtml="",$phpvarok="",$phpvarok1="",$phpvarok2="",$phpvarok3="")
	{
		if($funhtml)
		{
			eval($funhtml);// 执行字符串中的函数
		}
		if($datahtml)
		{
			$datahtml = addslashes($datahtml);
			eval("\$datahtml = \"$datahtml\";");// 执行字符串中的变量
			$datahtml = moduledatarevert($datahtml);
		}
		return array('funthml'=>$funhtml,'datahtml'=>$datahtml);
	}
}

/** PHP检测上传图片是否有木马
上传图片一般新手都验证了图片类型、图片大小，但有些没有验证图片是否有代码，也就是攻击者以图片的方式把木马传到了你的服务器，可以拿到你服务器所有权限
也可以用linux服务器上的木马扫描软件，比如 Clamav 支持命令行执行的，上传之后就扫一下，最可靠， 
$last_line = system('php /var/bin/clamdscan upload.jpg'); 
根据扫描结果就可以判断了
直接传参图片路径就可以检测，若是返回值为5，则立即删除
$rs = checkMuma("sucaihuo.png"); 
$tips = array( 
        "0" => "文件没问题", 
        "5" => "文件有毒", 
        "-1" => "文件没有上传" 
    );
压缩包有含木马图片文件，大家可以用来检测
使用方法：$rs = checkMuma("du.png");**/
function modulecheckhex($img="") {
    $status = 0;
    $tips = array(
        "0" => "文件没问题",
        "5" => "文件有毒",
        "-1" => "文件没有上传"
    );
    if (file_exists($img)) {
        $resource = fopen($img, 'rb');
        $fileSize = filesize($img);
        fseek($resource, 0);
        if ($fileSize > 512) { // 取头和尾
            $hexCode = bin2hex(fread($resource, 512));
            fseek($resource, $fileSize - 512);
            $hexCode .= bin2hex(fread($resource, 512));
        } else { // 取全部
            $hexCode = bin2hex(fread($resource, $fileSize));
        }
        fclose($resource);
        /* 匹配16进制中的 <% ( ) %> */
        /* 匹配16进制中的 <? ( ) ?> */
        /* 匹配16进制中的 <script | /script> 大小写亦可 */
        if (preg_match("/(3c25.*?28.*?29.*?253e)|(3c3f.*?28.*?29.*?3f3e)|(3C534352495054)|(2F5343524950543E)|(3C736372697074)|(2F7363726970743E)/is", $hexCode)) {
            $status = 5;
        }
    } else {
        $status = -1;
    }
    return $tips[$status];
}

// 数据提交防灌水检查，表单提交是否来自于本站
function modulechecksubmit()
{	
	$moduletoken = moduleaqvarval('moduletoken','string');
	if((!empty($_SESSION['moduletoken']) && $_SESSION['moduletoken'] == $moduletoken) && 
	(empty($_SERVER['HTTP_REFERER']) || preg_replace("/https?:\/\/([^\:\/]+).*/i", "\\1", $_SERVER['HTTP_REFERER']) == preg_replace("/([^\:]+).*/", "\\1", $_SERVER['HTTP_HOST'])))
	{
		unset($_SESSION["moduletoken"]);// 删除验证码session,限制重复使用而出现的灌水
		return TRUE;
	}
	return FALSE;
}

// 数据提交防灌水检查，验证码验证
function modulecheckcode($codename="")
{
	$checkok = 0;
	
	// 判断验证码
	if(moduleaqvarval($codename,'string'))
	{
		$validate=moduleaqvarval($codename,'string');
		if($validate==$_SESSION["moduleimgcode"]){
			$checkok = 1;
			unset($_SESSION["moduleimgcode"]);// 删除验证码session,限制重复使用而出现的灌水
		}
	}
	
	return $checkok;
}

// html转实体
function htmlzst($html="")
{
	$html = str_replace("#moduley;","&#39;",$html);	
	$html = htmlspecialchars($html);
	
	return $html;
}

// 实体转html
function stzhtml($html="")
{
	$html = str_replace("#moduley;","&#39;",$html);
	$html = htmlspecialchars_decode($html);	
	
	return $html;
}

/* 利用文件锁处理高并发（文件锁）-用户访问锁定（多用户同时访问只执行一次）
** 利用flock()函数对文件进行加锁（排它锁），实现并发按序进行。
** flock(file,lock,block)有三个参数。
** file：已经打开的文件
** lock：锁的类型
** LOCK_SH：共享锁（读锁）
** LOCK_EX：独占锁定（排它锁，写锁）
** LOCK_UN：解锁
** LOCK_NB：如果希望在文件锁定时阻塞进程，那么需要加上该参数
** block：设置为true的时候，锁定文件时，会阻止其他进程
***********************************************
// * 阻塞模式（后面的进程会一直等待前面的进程执行完毕）
【一】.阻塞模式：(如果其他进程已经加锁文件,当前进程会一直等其他进程解锁文件后继续执行)
public function createOrder1(){
	$file = fopen(__DIR__.'/lock.txt','w+');
	//加锁
	if(flock($file,LOCK_EX)){
		//TODO 执行业务代码
		flock($file,LOCK_UN);//解锁
	}
	//关闭文件
	fclose($file);
}

// * 非阻塞模式（只要当前文件有锁存在，那么直接返回）
【二】.非阻塞模式：(如果其他进程已经加锁文件,当前进程不会等其他进程解锁文件,而是走else)
public function createOrder2(){
	$file = fopen(__DIR__.'/lock.txt','w+');
	//加锁
	if(flock($file,LOCK_EX|LOCK_NB)){
		//TODO 执行业务代码
		flock($file,LOCK_UN);//解锁
	}else{
		//TODO 执行业务代码 返回系统繁忙等错误提示
	}
	//关闭文件
	fclose($file);
}
********************************************/
function useraccessflock($fileurl="",$opfun="")
{
	$file = fopen($fileurl,"w+");

	// 排它性的锁定
	if(flock($file, LOCK_EX + LOCK_NB))
	{
		$opfun();
		fwrite($file,"Write something");
		// release lock
		flock($file,LOCK_UN);
	}
	else
	{
		return "Error locking file!";
	}
	
	fclose($file);	
}
?>